package p04;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * bean后处理器负责对bean生命周期的各个阶段注解进行解析
 * AutowiredAnnotationBeanPostProcessor  --->  @Autowired,@Value
 * CommonAnnotationBeanPostProcessor   --->   @Resource,@PostConstruct,@PreDestroy
 *
 * @author Chen weishuai
 * @since 2025/7/18
 */
public class UsualBeanPostProcessorDemo2 {
    public static void main(String[] args) {
        // 原生容器 vs 干净的容器
        // DefaultListableBeanFactory vs GenericApplicationContext
        /**
         * 这里用GenericApplicationContext来做测试，这是一个干净的容器
         * 这个容器中只要加了后处理器,调用refresh()方法就会自动运行beanFactory后处理器、bean后处理器和初始化单例，
         *  并且对bean后处理器进行了排序
         * DefaultListableBeanFactory相对而来太原生了
         */
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("bean3", Bean3.class);
        /**
         * 下面演示依次添加bean后处理器
         * 添加一个bean后处理器，bean的生命周期就会丰富一点
         */
        //springboot的后处理器，解析 @ConfigurationProperties，Bean初始化前执行
        ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());

        /**
         * 上面把bean后处理器注册成bean，但对spring容器来说，此时他们就是普通的bean，要是他们能够作为bean后处理器生效，必须运行他们
         * 这行代码的功能是:执行beanFactory后处理器，添加bean后处理器，初始化单例
         */
        context.refresh();
        //通过观察打印了哪些信息，就能判断哪些注解生效了
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println("====>" + context.getBean(name));
        }
        context.close();
    }

    @Slf4j
    @ConfigurationProperties(prefix = "java")
    @Data
    static class Bean3 {
        private String home;
        private String version;

        public Bean3() {
            log.warn("创建了bean3");
        }
    }
}
